package com.itcs.app.tran;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.text.MessageFormat;
import java.util.HashMap;
import java.util.Map;

import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Component;

import com.alibaba.dubbo.common.json.ParseException;
import com.alibaba.fastjson.JSON;
import com.itcs.app.pay.model.TradePayModel;
import com.itcs.app.pay.model.TradePayRes;
import com.itcs.app.pay.service.PayService;
import com.itcs.app.service.TransJournalService;
import com.itcs.app.util.PayChannelCode;
import com.itcs.app.util.PayResult;
import com.itcs.app.util.PayStatus;
import com.itcs.app.util.PayType;
import com.itcs.box.BoxConstants;
import com.itcs.box.domain.BoxData;
import com.itcs.box.domain.BoxRequest;
import com.itcs.box.domain.BoxResponse;
import com.itcs.box.util.BoxResUtils;
import com.itcs.box.util.LogUtils;
import com.itcs.dubbo.service.DubboServiceAdapter;
import com.itcs.trading.mapper.TransJournalMapper;
import com.itcs.trading.model.TransJournal;

/**
 * 终端向后台发送付款码和支付请求 被扫
 * 
 * @author LiuPeng
 * @date 2017年12月9日
 * 
 */
@Component
public class BoxTran1015 implements DubboServiceAdapter {
	private Log logger = LogFactory.getLog(getClass());

	/**
	 * @Fields 订单名
	 */
	@Value("${mhtOrderName}")
	private String orderName;
	/**
	 * @Fields 订单详情
	 */
	@Value("${mhtOrderDetail}")
	private String orderDetail;

	@Autowired
	private TransJournalMapper transJournalMapper;
	@Autowired
	private TransJournalService transJournalService;
	@Autowired
	private PayService payService;

	@Override
	public String getTrancode() {
		return "box_1015";
	}

	public String getTranDescription() {
		return "被扫";
	}

	@Override
	public Map<String, Object> exchange(Map<String, Object> reqRecord) {

		logger.info(LogUtils.build(getTrancode(), getTranDescription(), "接收被扫请求", JSON.toJSONString(reqRecord)));

		Map<String, Object> res = new HashMap<>();
		BoxResponse boxResponse = new BoxResponse();
		BoxData responseData = new BoxData();
		boxResponse.setData(responseData);
		try {
			BoxRequest boxRequest = (BoxRequest) reqRecord.get(BoxConstants.BOX_REQ_KEY);
			boxResponse = beisao(boxRequest);
			res.put(BoxConstants.BOX_RES_KEY, boxResponse);
		} catch (Exception e) {
			responseData.setResult("9"); // 其他异常或数据库异常
			logger.error(LogUtils.build(getTrancode(), getTranDescription(), "处理失败," + e.getMessage()), e);
		}

		return res;
	}

	/**
	 * 被扫业务处理
	 * 
	 * @param boxRequest
	 * @return
	 * @throws ParseException
	 */
	private BoxResponse beisao(BoxRequest boxRequest) throws ParseException {

		BoxData boxRequestData = boxRequest.getData();

		String authCode = boxRequestData.getPayCode();
		String payChannelCode = PayChannelCode.微信支付;
		int payerId = PayType.被扫微信;
		if (authCode.startsWith("28")) {
			payChannelCode = PayChannelCode.支付宝支付;
			payerId = PayType.被扫支付宝;
		}

		try {
			TransJournal etds = transJournalService.selectByTransNo(boxRequestData.getTransacSeq());
			if (etds == null || boxRequestData.getTransacSeq() == null) {
				// 订单不存在,新建订单
				etds = new TransJournal(boxRequestData.getTransacSeq(), new BigDecimal(boxRequestData.getTollFare()),
						Long.parseLong(boxRequestData.getDeviceId()), payerId, boxRequestData.getRequestTime());
				transJournalMapper.insert(etds);
			} else if (etds.getPayState() != null) {// 如果订单存在
				if (etds.getPayState() == 2) {
					// 如果已付，则直接返回
					logger.info(LogUtils.build(getTrancode(), getTranDescription(), "流水号:" + boxRequestData.getTransacSeq() + " 已被支付",
							JSON.toJSONString(boxRequestData)));

					BoxResponse response2008 = BoxResUtils.build2008(boxRequestData, PayResult.其他, PayType.BOX_二维码, payChannelCode, null);
					return response2008;
				} else if (etds.getPayState() == 5) {
					logger.info(LogUtils.build(getTrancode(), getTranDescription(), "流水号:" + boxRequestData.getTransacSeq() + " 该交易已完成",
							JSON.toJSONString(boxRequestData)));

					BoxResponse response2008 = BoxResUtils.build2008(boxRequestData, PayResult.其他, PayType.BOX_二维码, payChannelCode, null);
					return response2008;
				}
			}

			// 支付金额
			BigDecimal tollFareValue = new BigDecimal(boxRequestData.getTollFare());
			String tollFareYStr = tollFareValue.divide(new BigDecimal(100), 2, RoundingMode.HALF_UP).toString();
			String mhtOrderDetail = MessageFormat.format(orderDetail, tollFareYStr);

			TradePayModel tradePayModel = new TradePayModel(payChannelCode, orderName, mhtOrderDetail, Integer.parseInt(boxRequestData.getTollFare()),
					null, boxRequestData.getTransacSeq(), authCode, "127.0.0.1");
			TradePayRes tradePayRes = payService.tradePay(tradePayModel);

			logger.info(LogUtils.build(getTrancode(), getTranDescription(), "流水号:" + boxRequestData.getTransacSeq() + " 被扫调用第三方支付完成,返回码:"
					+ tradePayRes.getRescode() + ",payStatus:" + tradePayRes.getPayStatus()));

			if (TradePayRes.PAY_SUCCESS.equals(tradePayRes.getPayStatus())) {
				etds.setPayState(PayStatus.支付成功);// 完成支付
				etds.setRemark(tradePayRes.getOpenid());// 添加用户标示
				String nowPayOrderNo = tradePayRes.getPlatformOrderNo();
				if (nowPayOrderNo != null) {
					etds.setdOrderNo(nowPayOrderNo);// 第三方支付流水号 聚合订单号
				}
				String channelOrderNo = tradePayRes.getChannelOrderNo();
				if (channelOrderNo != null) {
					etds.setsOrderNo(channelOrderNo);// 渠道订单号,微信或支付宝订单号,支付成功时返回 第三方订单号
				}
				// 更新流水信息
				transJournalMapper.updateByPrimaryKey(etds);

				BoxResponse response2008 = BoxResUtils.build2008(boxRequestData, PayResult.成功, PayType.BOX_二维码, payChannelCode, null);

				logger.info(LogUtils.build(getTrancode(), getTranDescription(), "流水号:" + boxRequestData.getTransacSeq() + " 支付成功，返回支付成功通知(2008)",
						JSON.toJSONString(response2008)));

				return response2008;

			} else if (TradePayRes.PAY_FAILED.equals(tradePayRes.getPayStatus())) {
				etds.setPayState(PayStatus.支付失败);// 支付失败
				transJournalMapper.updateByPrimaryKey(etds); // 更新流水信息

				BoxResponse response2008 = BoxResUtils.build2008(boxRequestData, PayResult.其他, PayType.BOX_二维码, payChannelCode, null);

				logger.info(LogUtils.build(getTrancode(), getTranDescription(), "流水号:" + boxRequestData.getTransacSeq() + " 支付失败，返回支付失败消息(2008)",
						JSON.toJSONString(response2008)));

				return response2008;
			} else {
				etds.setPayState(PayStatus.待支付);// 待支付
				transJournalMapper.updateByPrimaryKey(etds); // 更新流水信息

				logger.info(LogUtils.build(getTrancode(), getTranDescription(), "流水号:" + boxRequestData.getTransacSeq() + " 等待现在支付回调"));
			}

		} catch (Exception ex) {

			logger.error(LogUtils.build(getTrancode(), getTranDescription(), "流水号:" + boxRequestData.getTransacSeq() + " 处理异常,返回异常消息(2008)",
					JSON.toJSONString(boxRequestData)), ex);

			BoxResponse response2008 = BoxResUtils.build2008(boxRequestData, PayResult.其他, PayType.BOX_二维码, payChannelCode, null);
			return response2008;
		}

		return null;
	}
}
